﻿using BenCaoXuan.Infrastructure.Attr;
using BenCaoXuan.Infrastructure.Dto;
using BenCaoXuan.Infrastructure.Dto.Admin.employee;
using BenCaoXuan.Infrastructure.Dto.Admin.System;
using BenCaoXuan.Infrastructure.EFCore.MySql;
using BenCaoXuan.Infrastructure.IOC;
using BenCaoXuan.Infrastructure.Tools;
using BenCaoXuan.Service.Interface.admin;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BenCaoXuan.Service.Instance.admin
{
    [Inject_]
    public class Sys_Service : Base_Service, I_Sys_Service
    {
        private readonly Sys_IOC _sys_IOC;
        private readonly Login_IOC _login_IOC;

        public Sys_Service(Sys_IOC sys_IOC, Login_IOC login_IOC)
        {
            _sys_IOC = sys_IOC;
            _login_IOC = login_IOC;
        }

        /// <summary>
        /// 获取部门
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Get_Department()
        {
            //获取所有部门
            var dept = await _sys_IOC._sysDepartment_EFCore.GetAll().ToListAsync();
            //获取所有员工
            var employee = _login_IOC._sysEmployee_EFCore.GetAll().ToList();
            //获取顶级部门
            var root = dept.Where(d => d.DParentId == null && string.IsNullOrEmpty(d.DParentId)).ToList();
            List<SysDept_Dto> list = new List<SysDept_Dto>();
            root.ForEach(d =>
            {
                list.Add(new SysDept_Dto()
                {
                    key = d.DId,
                    icon = d.DIcon,
                    title = d.DName,
                    deptLv = d.DLv,
                    children = Get_Children_Dept(d.DId, dept, employee),
                    count = Get_Dept_Count(d.DId, dept, employee)
                });
            });

            return Get_Result(0, "ok", list);

        }

        /// <summary>
        /// 获取部门下的员工数量
        /// </summary>
        /// <param name="dId"></param>
        /// <param name="dept"></param>
        /// <param name="employee"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private int? Get_Dept_Count(string dId, List<SysDepartment> dept, List<SysEmployee> employee)
        {
            // 获取当前部门的直接用户数
            int count = employee.Count(d => d.EDepartmentId == dId);

            // 获取所有子部门
            var children = dept.Where(d => d.DParentId == dId).ToList();

            // 递归获取子部门的用户数
            foreach (var child in children)
            {
                count += Get_Dept_Count(child.DId, dept, employee) ?? 0;
            }

            return count;
        }

        /// <summary>
        /// 获取子级部门
        /// </summary>
        /// <param name="dId"></param>
        /// <param name="dept"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private List<SysDept_Dto> Get_Children_Dept(string dId, List<SysDepartment> dept, List<SysEmployee> employee)
        {
            var root = dept.Where(d => d.DParentId == dId).ToList();
            List<SysDept_Dto> list = new List<SysDept_Dto>();
            root.ForEach(d =>
            {
                list.Add(new SysDept_Dto()
                {
                    key = d.DId,
                    icon = d.DIcon,
                    title = d.DName,
                    deptLv = d.DLv,
                    children = Get_Children_Dept(d.DId, dept, employee),
                    count = Get_Dept_Count(d.DId, dept, employee)
                });
            });

            return list;
        }

        /// <summary>
        /// 获取菜单
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Get_Menu()
        {
            var allMenu = await _sys_IOC._sysRight_EFCore.GetAll(true, o => o.RNo).ToListAsync();
            var allParent = allMenu.Where(d => d.RParent == null && string.IsNullOrEmpty(d.RParent)).ToList();
            List<SysRight_Dto> list = new List<SysRight_Dto>();
            allParent.ForEach(d =>
            {
                list.Add(new SysRight_Dto()
                {
                    id = d.RId,
                    icon = d.RIcon,
                    name = d.RName,
                    no = d.RNo,
                    url = string.IsNullOrEmpty(d.RUrl) ? Config.GUID2() : d.RUrl,
                    children = Get_Children_Menu(d.RId, allMenu)

                });
            });

            return Get_Result(0, "ok", list);
        }

        /// <summary>
        /// 获取子级菜单
        /// </summary>
        /// <param name="rId"></param>
        /// <param name="allMenu"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private List<SysRight_Dto> Get_Children_Menu(string rId, List<SysRight> allMenu)
        {
            var all = allMenu.Where(d => d.RParent == rId).ToList();
            List<SysRight_Dto> list = new List<SysRight_Dto>();
            all.ForEach(d =>
            {
                list.Add(new SysRight_Dto()
                {
                    id = d.RId,
                    icon = d.RIcon,
                    name = d.RName,
                    no = d.RNo,
                    url = string.IsNullOrEmpty(d.RUrl) ? Config.GUID2() : d.RUrl,
                    children = Get_Children_Menu(d.RId, allMenu)

                });
            });

            return list;
        }

        /// <summary>
        /// 获取部门下的员工
        /// </summary>
        /// <param name="fenye_Dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Get_Dept_Employee(Fenye_Dto dto)
        {
            var dept = _sys_IOC._sysDepartment_EFCore.GetAll().ToList();
            // 获取子级用户
            var list = GetChildrenUser(dto.id, dept);
            list.Add(dto.id);

            var data = await _login_IOC._sysEmployee_EFCore
                .GetAll(out int total, dto.page, dto.limit, false, o => o.ECreateTime,
                d => list.Contains(d.EDepartmentId!) && d.EName!.Contains(dto.key))
                .Select(d => new Employee_Dto
                {
                    id = d.EId,
                    address = d.EAddress,
                    d_id = d.EDepartmentId,
                    account = d.EAccount,
                    isBan = d.EIsBan == 0 ? true : false,
                    name = d.EName,
                    photo = d.EPhoto,
                    phone = d.EPhone,
                    gender = d.EGender == 1 ? "男" : "女",
                    p_id = d.EPostId,
                    time = d.ECreateTime!.Value.ToString("yyyy-MM-dd HH:mm:ss"),

                    status = d.EStatus == 1 ? "在职" : "离职"
                }).ToListAsync();

            var post = _sys_IOC._sysPost_EFCore.GetAll().ToList();
            data.ForEach(d =>
            {
                d.deptName = dept.Where(c => c.DId == d.d_id).Select(c => c.DName).SingleOrDefault();
                d.postName = post.Where(c => c.PId == d.p_id).Select(c => c.PName).SingleOrDefault();

            });

            return Get_Result(0, "ok", new
            {
                data = data,
                total = total
            });
        }

        /// <summary>
        /// 获取子级部门下的员工
        /// </summary>
        /// <param name="id"></param>
        /// <param name="dept"></param>
        /// <returns></returns>
        private List<string> GetChildrenUser(string? id, List<SysDepartment> dept)
        {
            List<string> list = new List<string>();
            var children = dept.Where(d => d.DParentId == id).ToList();
            children.ForEach(d =>
            {
                list.Add(d.DId);
                var son = GetChildrenUser(d.DId, dept);
                if (son.Count > 0)
                {
                    list.AddRange(son);
                }
            });

            return list;
        }

        /// <summary>
        /// 获取部门下可选的岗位
        /// </summary>
        /// <param name="lv"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Get_Dept_Post(string? lv)
        {
            var post = await _sys_IOC._sysPost_EFCore.GetAll(d => d.PLv == lv)
                .Select(d => new SysPost_Dto
                {
                    id = d.PId,
                    name = d.PName,

                }).ToListAsync();

            return Get_Result(0, "ok", post);
        }

        /// <summary>
        /// 新增部门
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Add_Dept(AddDept_Dto dto)
        {
            SysDepartment sysDepartment = new SysDepartment()
            {
                DId = Config.GUID2(),
                DCreateTime = DateTime.Now,
                DIcon = dto.icon,
                DIsBan = 0,
                DLv = dto.lv,
                DName = dto.deptName,
                DParentId = dto.parentId,
                DRemark = dto.deptDesc
            };
            _sys_IOC._sysDepartment_EFCore.Add(sysDepartment);
            _sys_IOC._sysDepartment_EFCore.SaveChanges();
            List<SysDepartmentPostDetail> sysPosts = new List<SysDepartmentPostDetail>();
            dto.post!.ForEach(d =>
            {
                sysPosts.Add(new SysDepartmentPostDetail()
                {
                    DpId = Config.GUID2(),
                    DpCreateTime = DateTime.Now,
                    DpDid = sysDepartment.DId,
                    DpPid = d
                });
            });
            _sys_IOC._sysDepartmentPost_EFCore.AddRange(sysPosts);
            var result = await _sys_IOC._sysDepartmentPost_EFCore.SaveChangesAsync();
            return Get_Result(result);


        }

        /// <summary>
        /// 删除部门
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Delete_Dept(Delete_Dto dto)
        {
            var dept = await _sys_IOC._sysDepartment_EFCore.GetAll(d => d.DId == dto.id).SingleAsync();
            _sys_IOC._sysDepartment_EFCore.Delete(dept);

            var deptPost = await _sys_IOC._sysDepartmentPost_EFCore.GetAll(d => d.DpDid == dto.id).ToListAsync();
            _sys_IOC._sysDepartmentPost_EFCore.DeleteRange(deptPost);

            var result = _sys_IOC._sysDepartment_EFCore.Transactions(_sys_IOC._sysDepartmentPost_EFCore);
            return Get_Result(result ? 0 : -1);

        }

        /// <summary>
        ///  获取部门下所有的岗位
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Get_DeptPost(string id)
        {
            //当前部门下所有的岗位id
            var allPost = await _sys_IOC._sysDepartmentPost_EFCore.GetAll(d => d.DpDid == id)
                 .Select(d => d.DpPid).ToListAsync();
            //找到对应岗位的信息
            var data = await _sys_IOC._sysPost_EFCore.GetAll(d => allPost.Contains(d.PId))
                .Select(d => new SysPost_Dto
                {
                    id = d.PId,
                    name = d.PName
                }).ToListAsync();

            return Get_Result(0, "ok", data);
        }

        /// <summary>
        /// 新增员工
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Add_Employee(AddEmployee_Dto dto)
        {
            var salt = Config.GUID();
            var encryptedPassword = EncryptUtil.LoginMd5("123456", salt);

            SysEmployee sysEmployee = new SysEmployee()
            {
                EId = Config.GUID2(),
                EAccount = dto.phone,
                EAddress = dto.address,
                EDepartmentId = dto.deptId,
                EGender = dto.gender ? 1 : 0,
                EIsBan = 0,
                EName = dto.name,
                EPassword = encryptedPassword,  // 直接使用加密后的密码
                EPhone = dto.phone,
                EPhoto = dto.avatar,
                EPostId = dto.postId,
                ERemark = null,
                ESalt = salt,  // 直接设置salt
                ESpecialties = dto.specialty,
                EStatus = 1,
                ECreateTime = DateTime.Now,
                ELeisure=0
            };

            _login_IOC._sysEmployee_EFCore.Add(sysEmployee);
            var result = await _login_IOC._sysEmployee_EFCore.SaveChangesAsync();

            return Get_Result(result);
        }

        /// <summary>
        /// 编辑员工
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Update_Employee(UpdateEmployee_Dto dto)
        {
            var data = await _login_IOC._sysEmployee_EFCore.GetAll(d => d.EId == dto.id).SingleAsync();
            data.EPhone = dto.phone;
            data.EGender = dto.gender == "男" ? 1 : 0;
            data.EAddress = dto.address;
            data.EAccount = dto.phone;
            data.EDepartmentId = dto.dept;
            data.EPostId = dto.position;
            _login_IOC._sysEmployee_EFCore.Update(data);
            var result = await _login_IOC._sysEmployee_EFCore.SaveChangesAsync();
            return Get_Result(result);


        }

        /// <summary>
        /// 删除员工
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Delete_Employee(Delete_Dto dto)
        {
            var data = await _login_IOC._sysEmployee_EFCore.GetAll(d => d.EId == dto.id).SingleAsync();
            _login_IOC._sysEmployee_EFCore.Delete(data);
            var result = await _login_IOC._sysEmployee_EFCore.SaveChangesAsync();
            return Get_Result(result);
        }

        /// <summary>
        /// 切换员工的账号状态
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> ChangeIsBan_Employee(IsBan_Dto dto)
        {
            var data = await _login_IOC._sysEmployee_EFCore.GetAll(d => d.EId == dto.id).SingleAsync();
            data.EIsBan = dto.isBan ? 0 : 1;
            _login_IOC._sysEmployee_EFCore.Update(data);
            var result = await _login_IOC._sysEmployee_EFCore.SaveChangesAsync();
            return Get_Result(result);
        }

        /// <summary>
        /// 获取所有岗位
        /// </summary>
        /// <param name="fenye_Dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Get_AllPost(Fenye_Dto dto)
        {
            var data = await _sys_IOC._sysPost_EFCore
                .GetAll(out int total, dto.page, dto.limit, false, o => o.PCreateTime, d => d.PName.Contains(dto.key))
                .Select(d => new SysPost_Dto()
                {
                    id = d.PId,
                    isBan = d.PIsBan == 0 ? true : false,
                    name = d.PName,
                    lv = d.PLv,
                    allResponsibility = d.PResponsibility,
                    time = d.PCreateTime!.Value.ToString("yyyy-MM-dd HH:mm:ss"),
                }).ToListAsync();
            var employee = _login_IOC._sysEmployee_EFCore.GetAll().ToList();
            data.ForEach(d =>
            {
                d.count = employee.Where(c => c.EPostId == d.id).Count();
                d.responsibility = d.allResponsibility?.Split(",").ToList();
            });

            return Get_Result(0, "ok", new
            {
                data = data,
                total = total
            });
        }

        /// <summary>
        /// 新增岗位
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Add_Post(AddPost_Dto dto)
        {
            SysPost sysPost = new SysPost()
            {
                PId = Config.GUID(),
                PIsBan = 0,
                PLv = dto.level,
                PName = dto.name,
                PRemark = dto.remark,
                PResponsibility = dto.responsibility,
                PCreateTime = DateTime.Now
            };

            _sys_IOC._sysPost_EFCore.Add(sysPost);
            var result = await _sys_IOC._sysPost_EFCore.SaveChangesAsync();
            return Get_Result(result);
        }

        /// <summary>
        /// 获取岗位下的人员
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Get_Post_Employee(Fenye_Dto dto)
        {
            var data = await _login_IOC._sysEmployee_EFCore
                .GetAll(out int total,dto.page,dto.limit,false,o=>o.ECreateTime,d => d.EPostId == dto.id)
                .Select(d => new Employee_Dto()
                {
                    id = d.EId,
                    address = d.EAddress,
                    d_id = d.EDepartmentId,
                    account = d.EAccount,
                    isBan = d.EIsBan == 0 ? true : false,
                    name = d.EName,
                    photo = d.EPhoto,
                    phone = d.EPhone,
                    gender = d.EGender == 1 ? "男" : "女",
                    p_id = d.EPostId,
                    time = d.ECreateTime!.Value.ToString("yyyy-MM-dd HH:mm:ss"),

                    status = d.EStatus == 1 ? "在职" : "离职"
                }).ToListAsync();
            var dept = _sys_IOC._sysDepartment_EFCore.GetAll().ToList();
            var post = _sys_IOC._sysPost_EFCore.GetAll().ToList();
            data.ForEach(d =>
            {
                d.deptName = dept.Where(c => c.DId == d.d_id).Select(c => c.DName).SingleOrDefault();
                d.postName = post.Where(c => c.PId == d.p_id).Select(c => c.PName).SingleOrDefault();

            });

            return Get_Result(0, "ok", new
            {
                data = data,
                total = total
            });
        }

        /// <summary>
        /// 删除岗位
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Delete_Post(Delete_Dto dto)
        {
            var data =await _sys_IOC._sysPost_EFCore.GetAll(d => d.PId == dto.id).SingleAsync();
            _sys_IOC._sysPost_EFCore.Delete(data);
            var result =await _sys_IOC._sysPost_EFCore.SaveChangesAsync();
            return Get_Result(result);
        }

        /// <summary>
        /// 获取所有的父级字典列表
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Get_Dictionary()
        {
            var data =await _sys_IOC._sysDictionary_EFCore
                .GetAll(d=>d.DIsType==1)
                .Select(d => new SysDictionary_Dto{
                id=d.DId,
                icon=d.DIcon,
                name=d.DName,
                
                }).ToListAsync();
            data.ForEach(d => {
                d.count = _sys_IOC._sysDictionary_EFCore.GetAll(c => c.DParentId == d.id).Count();
            });

            return Get_Result(0, "ok", data);
        }

        /// <summary>
        /// 获取子级字典
        /// </summary>
        /// <param name="fenye_Dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Get_Children_Dictionary(Fenye_Dto dto)
        {
            var data =await _sys_IOC._sysDictionary_EFCore
                 .GetAll(out int total, dto.page, dto.limit,
                 false, o => o.DCreateTime, d => d.DParentId == dto.id && d.DName!.Contains(dto.key))
                 .Select(d => new SysDictionary_Dto{
                 id= d.DId,
                 icon = d.DIcon,
                 name = d.DName,
                 isBan=d.DIsBan==0?true:false,
                 p_id=d.DParentId,
                 time = d.DCreateTime!.Value.ToString("yyyy-MM-dd HH:mm:ss"),
                 }).ToListAsync();
            var all = _sys_IOC._sysDictionary_EFCore.GetAll().ToList();
            data.ForEach(d => {
                d.p_name = all.Where(c => d.p_id == c.DId).Select(c => c.DName).Single();
            });

            return Get_Result(0, "ok", new { 
            data=data,
            total=total,
            });


        }

        /// <summary>
        /// 编辑字典
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Update_Dictionary(UpdateDictionary_Dto dto)
        {
            var data =await _sys_IOC._sysDictionary_EFCore.GetAll(d => d.DId == dto.id).SingleAsync();
            data.DIcon = dto.icon;
            data.DName = dto.name;
            data.DRemark = dto.description;
            _sys_IOC._sysDictionary_EFCore.Update(data);
            var result = await _sys_IOC._sysDictionary_EFCore.SaveChangesAsync();
            return Get_Result(result);
        }

        /// <summary>
        /// 修改字典的状态
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> ChangeIsBan_Dictionary(IsBan_Dto dto)
        {
            var data =await _sys_IOC._sysDictionary_EFCore.GetAll(d => d.DId == dto.id).SingleAsync();
            data.DIsBan = dto.isBan ? 0 : 1;
            _sys_IOC._sysDictionary_EFCore.Update(data);
            var result = await _sys_IOC._sysDictionary_EFCore.SaveChangesAsync();
            return Get_Result(result);
        }

        /// <summary>
        /// 删除字典
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Delete_Dictionary(Delete_Dto dto)
        {
            var data =await _sys_IOC._sysDictionary_EFCore.GetAll(d => d.DId == dto.id).SingleAsync();
            _sys_IOC._sysDictionary_EFCore.Delete(data);
            var result = await _sys_IOC._sysDictionary_EFCore.SaveChangesAsync();
            return Get_Result(result);
        }

        /// <summary>
        /// 新增字典
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Add_Children_Dictionary(AddChildrenDictionary_Dto dto)
        {
           SysDictionary sysDictionary = new SysDictionary() { 
           DId=Config.GUID(),
           DIcon=dto.icon,
           DIsBan=0,
           DIsType=dto.parentId==null?1:0,
           DName=dto.name,
           DParentId=dto.parentId,
           DRemark=dto.description,
               DCreateTime=DateTime.Now,
           };
            _sys_IOC._sysDictionary_EFCore.Add(sysDictionary);
            var result = await _sys_IOC._sysDictionary_EFCore.SaveChangesAsync();
            return Get_Result(result);
        }

        /// <summary>
        /// 切换岗位状态
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> ChangeIsBan_Post(IsBan_Dto dto)
        {
            var data =await _sys_IOC._sysPost_EFCore.GetAll(d => d.PId == dto.id).SingleAsync();
            data.PIsBan = dto.isBan ? 0 : 1;
            _sys_IOC._sysPost_EFCore.Update(data);
            var result = await _sys_IOC._sysPost_EFCore.SaveChangesAsync();
            return Get_Result(result);
        }

        /// <summary>
        /// 获取对应的字典
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Get_DictionaryByType(string? key)
        {
            var id = _sys_IOC._sysDictionary_EFCore.GetAll(d => d.DName == key && d.DIsType == 1).Select(d => d.DId).Single();
            var data = await _sys_IOC._sysDictionary_EFCore.GetAll(d => d.DParentId == id)
                .Select(d => new SysDictionary_Dto()
                {
                    id = d.DId,
                    name = d.DName,
                }).ToListAsync();

            return Get_Result(0, "ok", data);
        }
    }
}
